import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { BehaviorSubject, Observable, throwError } from 'rxjs';
import { catchError, tap, map } from 'rxjs/operators';

/**
 * 库存警报规则接口
 */
export interface StockAlertRule {
  id: string;
  isGlobal: boolean;
  goodsCode?: string;
  goodsType?: string;
  warehouseName?: string;
  thresholdValue: number;
  priority: number;
  isActive: boolean;
  createdAt: Date;
  updatedAt: Date;
}

/**
 * 货品库存信息接口
 */
export interface StockItem {
  id: string;
  goodsCode: string;
  goodsName: string;
  specification: string;
  warehouseId: string;
  warehouseName: string;
  goodsType: string;
  currentStock: number;
  warningThreshold: number;
  unitPrice: number;
  totalAmount: number;
  updatedAt: Date;
}

/**
 * 库存统计信息接口
 */
export interface StockStats {
  totalStock: number;
  totalAmount: number;
  warehouseCount: number;
  typeCount: number;
  lastUpdateTime: Date;
}

/**
 * 按仓库分组的库存信息
 */
export interface WarehouseStockGroup {
  warehouseId: string;
  warehouseName: string;
  stockCount: number;
  stockAmount: number;
}

/**
 * 按货品类型分组的库存信息
 */
export interface TypeStockGroup {
  goodsType: string;
  stockCount: number;
  stockAmount: number;
}

/**
 * 库存数据服务
 * 集中管理库存相关的数据，提供数据共享和操作功能
 */
@Injectable({
  providedIn: 'root'
})
export class StockDataService {
  // 所有库存物品
  private stockItemsSubject = new BehaviorSubject<StockItem[]>([]);
  public stockItems$ = this.stockItemsSubject.asObservable();

  // 低库存物品
  private lowStockItemsSubject = new BehaviorSubject<StockItem[]>([]);
  public lowStockItems$ = this.lowStockItemsSubject.asObservable();

  // 库存统计数据
  private stockStatsSubject = new BehaviorSubject<StockStats>({
    totalStock: 0,
    totalAmount: 0,
    warehouseCount: 0,
    typeCount: 0,
    lastUpdateTime: new Date()
  });
  public stockStats$ = this.stockStatsSubject.asObservable();

  // 按仓库分组的库存数据
  private stockByWarehouseSubject = new BehaviorSubject<WarehouseStockGroup[]>([]);
  public stockByWarehouse$ = this.stockByWarehouseSubject.asObservable();

  // 按类型分组的库存数据
  private stockByTypeSubject = new BehaviorSubject<TypeStockGroup[]>([]);
  public stockByType$ = this.stockByTypeSubject.asObservable();

  // 预警规则列表
  private alertRulesSubject = new BehaviorSubject<StockAlertRule[]>([]);
  public alertRules$ = this.alertRulesSubject.asObservable();

  // 更新时间
  private lastUpdateTimeSubject = new BehaviorSubject<Date | null>(null);
  public lastUpdateTime$ = this.lastUpdateTimeSubject.asObservable();

  // 默认低库存阈值
  private defaultLowStockThreshold = 10;

  // 数据加载状态
  private loadingSubject = new BehaviorSubject<boolean>(false);
  public loading$ = this.loadingSubject.asObservable();

  // API URL
  private apiUrl = '/api/app/stocks';

  constructor(private http: HttpClient) {
    // 初始化默认阈值（从本地存储中获取，如果有的话）
    this.loadDefaultThreshold();
    
    // 初始化库存预警规则
    this.loadAlertRules();
  }

  /**
   * 刷新所有库存相关数据
   */
  refreshData(): void {
    this.loadingSubject.next(true);
    console.log('正在刷新库存数据...');
    
    // 首先尝试主API
    const mainApiUrl = `${this.apiUrl}/all`;
    console.log('尝试请求API:', mainApiUrl);

    this.http.get<any>(mainApiUrl).pipe(
      catchError(error => {
        console.warn('主API请求失败，尝试备用API:', error);
        // 尝试备用API
        const backupApiUrl = '/api/app/kucun-zhu-xinxi';
        return this.http.get<any>(backupApiUrl).pipe(
          catchError(backupError => {
            console.error('备用API也请求失败:', backupError);
            // 两个API都失败，使用模拟数据
            this.generateMockData();
            this.loadingSubject.next(false);
            return throwError(() => backupError);
          })
        );
      }),
      tap(response => {
        // 更新最后刷新时间
        const currentTime = new Date();
        this.lastUpdateTimeSubject.next(currentTime);

        console.log('API返回数据:', response);
        
        // 处理获取到的库存数据
        if (response && response.items) {
          // 标准API返回格式
          const stockItems = response.items as StockItem[];
          this.processReceivedItems(stockItems);
        } else if (response && Array.isArray(response)) {
          // 备用API可能直接返回数组
          this.processReceivedItems(response);
        } else {
          console.warn('API返回数据格式不符预期，使用模拟数据替代');
          this.generateMockData();
        }

        this.loadingSubject.next(false);
      })
    ).subscribe({
      error: () => {
        // 错误处理已在catchError中完成
        this.loadingSubject.next(false);
      }
    });
  }
  
  /**
   * 处理接收到的数据
   */
  private processReceivedItems(items: any[]): void {
    if (!items || items.length === 0) {
      console.warn('接收到的数据为空，使用模拟数据');
      this.generateMockData();
      return;
    }
    
    try {
      // 将数据转换为标准格式
      const stockItems = items.map(item => ({
        id: item.id || String(Math.random()),
        goodsCode: item.goodsCode || '',
        goodsName: item.goodsName || '',
        specification: item.specification || '',
        warehouseId: item.warehouseId || item.warehouseName || '',
        warehouseName: item.warehouseName || '',
        goodsType: item.goodsType || '',
        currentStock: Number(item.currentStock) || 0,
        warningThreshold: Number(item.warningThreshold) || 10,
        unitPrice: Number(item.unitPrice) || Number(item.stockAmount) / (Number(item.currentStock) || 1),
        totalAmount: Number(item.totalAmount) || Number(item.stockAmount) || 0,
        updatedAt: new Date()
      } as StockItem));
      
      console.log('转换后的数据:', stockItems.length, '条记录');
      
      // 更新库存物品列表
      this.stockItemsSubject.next(stockItems);
      
      // 处理低库存物品
      this.processlowStockItems(stockItems);
      
      // 计算库存统计数据
      this.calculateStockStats(stockItems);
      
      // 按仓库和类型分组
      this.groupStockByWarehouse(stockItems);
      this.groupStockByType(stockItems);
    } catch (error) {
      console.error('处理接收数据时出错:', error);
      this.generateMockData();
    }
  }

  /**
   * 生成模拟数据（当API不可用时）
   */
  private generateMockData(): void {
    console.log('生成模拟库存数据');
    
    // 生成模拟库存项
    const mockItems: StockItem[] = [
      {
        id: '1',
        goodsCode: 'G001',
        goodsName: '办公电脑',
        specification: '14寸',
        warehouseId: '1',
        warehouseName: '主仓库',
        goodsType: '办公设备',
        currentStock: 125,
        warningThreshold: 20,
        unitPrice: 5000,
        totalAmount: 625000,
        updatedAt: new Date()
      },
      {
        id: '2',
        goodsCode: 'G002',
        goodsName: '打印纸',
        specification: 'A4',
        warehouseId: '2',
        warehouseName: '办公仓库',
        goodsType: '办公用品',
        currentStock: 500,
        warningThreshold: 100,
        unitPrice: 20,
        totalAmount: 10000,
        updatedAt: new Date()
      },
      {
        id: '3',
        goodsCode: 'G003',
        goodsName: '矿泉水',
        specification: '550ml',
        warehouseId: '3',
        warehouseName: '食品仓库',
        goodsType: '食品饮料',
        currentStock: 1000,
        warningThreshold: 200,
        unitPrice: 2,
        totalAmount: 2000,
        updatedAt: new Date()
      }
    ];

    // 更新库存物品列表
    this.stockItemsSubject.next(mockItems);
    
    // 处理低库存物品
    this.processlowStockItems(mockItems);
    
    // 计算库存统计数据
    this.calculateStockStats(mockItems);
    
    // 按仓库和类型分组
    this.groupStockByWarehouse(mockItems);
    this.groupStockByType(mockItems);
    
    // 更新时间
    this.lastUpdateTimeSubject.next(new Date());
  }

  /**
   * 处理低库存物品
   */
  private processlowStockItems(items: StockItem[]): void {
    // 获取预警规则
    const rules = this.alertRulesSubject.value;
    
    // 获取低库存物品
    const lowStockItems = items.filter(item => {
      // 查找适用于此物品的最高优先级规则
      const matchingRule = this.findMatchingRule(item, rules);
      
      // 获取适用阈值（规则阈值或默认阈值）
      const threshold = matchingRule ? matchingRule.thresholdValue : this.defaultLowStockThreshold;
      
      // 如果当前库存低于阈值，标记为低库存
      return item.currentStock < threshold;
    });
    
    this.lowStockItemsSubject.next(lowStockItems);
  }

  /**
   * 为特定库存物品查找匹配的警报规则
   */
  findMatchingRule(item: StockItem, rules: StockAlertRule[]): StockAlertRule | null {
    // 过滤出启用的规则
    const activeRules = rules.filter(rule => rule.isActive);
    
    // 按优先级排序（从高到低）
    const sortedRules = activeRules.sort((a, b) => a.priority - b.priority);
    
    // 查找第一个匹配的规则
    for (const rule of sortedRules) {
      // 全局规则匹配所有物品
      if (rule.isGlobal) {
        return rule;
      }
      
      // 检查特定条件
      const matchesGoodsCode = !rule.goodsCode || rule.goodsCode === item.goodsCode;
      const matchesGoodsType = !rule.goodsType || rule.goodsType === item.goodsType;
      const matchesWarehouse = !rule.warehouseName || rule.warehouseName === item.warehouseName;
      
      // 如果所有指定条件都匹配，则使用此规则
      if (matchesGoodsCode && matchesGoodsType && matchesWarehouse) {
        return rule;
      }
    }
    
    // 没有匹配的规则
    return null;
  }

  /**
   * 计算库存统计数据
   */
  private calculateStockStats(items: StockItem[]): void {
    // 如果没有数据，提供默认值
    if (!items || items.length === 0) {
      const stats: StockStats = {
        totalStock: 0,
        totalAmount: 0,
        warehouseCount: 0,
        typeCount: 0,
        lastUpdateTime: new Date()
      };
      this.stockStatsSubject.next(stats);
      return;
    }

    try {
      // 计算总库存量
      const totalStock = items.reduce((sum, item) => sum + (item.currentStock || 0), 0);
      
      // 计算总金额
      const totalAmount = items.reduce((sum, item) => sum + ((item.currentStock || 0) * (item.unitPrice || 0)), 0);
      
      // 计算仓库数量（不重复）
      const warehouseCount = new Set(items.map(item => item.warehouseName)).size;
      
      // 计算货品类型数量（不重复）
      const typeCount = new Set(items.map(item => item.goodsType)).size;
      
      const stats: StockStats = {
        totalStock,
        totalAmount,
        warehouseCount,
        typeCount,
        lastUpdateTime: new Date()
      };
      
      this.stockStatsSubject.next(stats);
      
      // 将统计数据输出到控制台以方便调试
      console.log('库存统计数据:', stats);
    } catch (error) {
      console.error('计算库存统计数据时出错:', error);
      // 出错时使用默认值
      const stats: StockStats = {
        totalStock: 0,
        totalAmount: 0,
        warehouseCount: 0,
        typeCount: 0,
        lastUpdateTime: new Date()
      };
      this.stockStatsSubject.next(stats);
    }
  }

  /**
   * 按仓库分组库存数据
   */
  private groupStockByWarehouse(items: StockItem[]): void {
    // 如果没有数据，提供默认值
    if (!items || items.length === 0) {
      const defaultWarehouses: WarehouseStockGroup[] = [
        { warehouseId: '1', warehouseName: '主仓库', stockCount: 0, stockAmount: 0 },
        { warehouseId: '2', warehouseName: '办公仓库', stockCount: 0, stockAmount: 0 },
        { warehouseId: '3', warehouseName: '食品仓库', stockCount: 0, stockAmount: 0 }
      ];
      this.stockByWarehouseSubject.next(defaultWarehouses);
      return;
    }

    try {
      // 按仓库名称分组
      const warehouseGroups: { [key: string]: WarehouseStockGroup } = {};
      
      // 遍历所有物品
      items.forEach(item => {
        const warehouseId = item.warehouseId || 'unknown';
        const warehouseName = item.warehouseName || '未知仓库';
        const currentStock = item.currentStock || 0;
        const stockAmount = currentStock * (item.unitPrice || 0);
        
        // 如果这个仓库已经在分组中，累加数量
        if (warehouseGroups[warehouseId]) {
          warehouseGroups[warehouseId].stockCount += currentStock;
          warehouseGroups[warehouseId].stockAmount += stockAmount;
        } else {
          // 否则创建新分组
          warehouseGroups[warehouseId] = {
            warehouseId,
            warehouseName,
            stockCount: currentStock,
            stockAmount
          };
        }
      });
      
      // 转换为数组
      const result = Object.values(warehouseGroups);
      
      // 如果结果为空，添加默认值
      if (result.length === 0) {
        result.push({ warehouseId: '1', warehouseName: '主仓库', stockCount: 0, stockAmount: 0 });
      }
      
      this.stockByWarehouseSubject.next(result);
      
      // 输出到控制台以方便调试
      console.log('按仓库分组的库存数据:', result);
    } catch (error) {
      console.error('按仓库分组库存数据时出错:', error);
      // 出错时使用默认值
      const defaultWarehouses: WarehouseStockGroup[] = [
        { warehouseId: '1', warehouseName: '主仓库', stockCount: 0, stockAmount: 0 },
        { warehouseId: '2', warehouseName: '办公仓库', stockCount: 0, stockAmount: 0 }
      ];
      this.stockByWarehouseSubject.next(defaultWarehouses);
    }
  }

  /**
   * 按货品类型分组库存数据
   */
  private groupStockByType(items: StockItem[]): void {
    // 如果没有数据，提供默认值
    if (!items || items.length === 0) {
      const defaultTypes: TypeStockGroup[] = [
        { goodsType: '办公设备', stockCount: 0, stockAmount: 0 },
        { goodsType: '食品饮料', stockCount: 0, stockAmount: 0 },
        { goodsType: '电子产品', stockCount: 0, stockAmount: 0 },
        { goodsType: '办公用品', stockCount: 0, stockAmount: 0 },
        { goodsType: '家用类', stockCount: 0, stockAmount: 0 }
      ];
      this.stockByTypeSubject.next(defaultTypes);
      return;
    }

    try {
      // 按货品类型分组
      const typeGroups: { [key: string]: TypeStockGroup } = {};
      
      // 遍历所有物品
      items.forEach(item => {
        const goodsType = item.goodsType || '未分类';
        const currentStock = item.currentStock || 0;
        const stockAmount = currentStock * (item.unitPrice || 0);
        
        // 如果这个类型已经在分组中，累加数量
        if (typeGroups[goodsType]) {
          typeGroups[goodsType].stockCount += currentStock;
          typeGroups[goodsType].stockAmount += stockAmount;
        } else {
          // 否则创建新分组
          typeGroups[goodsType] = {
            goodsType,
            stockCount: currentStock,
            stockAmount
          };
        }
      });
      
      // 转换为数组
      const result = Object.values(typeGroups);
      
      // 如果结果为空，添加默认值
      if (result.length === 0) {
        result.push(
          { goodsType: '办公设备', stockCount: 0, stockAmount: 0 },
          { goodsType: '电子产品', stockCount: 0, stockAmount: 0 }
        );
      }
      
      // 按数量排序
      result.sort((a, b) => b.stockCount - a.stockCount);
      
      this.stockByTypeSubject.next(result);
      
      // 输出到控制台以方便调试
      console.log('按类型分组的库存数据:', result);
    } catch (error) {
      console.error('按类型分组库存数据时出错:', error);
      // 出错时使用默认值
      const defaultTypes: TypeStockGroup[] = [
        { goodsType: '办公设备', stockCount: 0, stockAmount: 0 },
        { goodsType: '食品饮料', stockCount: 0, stockAmount: 0 },
        { goodsType: '电子产品', stockCount: 0, stockAmount: 0 }
      ];
      this.stockByTypeSubject.next(defaultTypes);
    }
  }

  /**
   * 获取默认低库存阈值
   */
  getDefaultLowStockThreshold(): number {
    return this.defaultLowStockThreshold;
  }

  /**
   * 设置默认低库存阈值
   */
  setDefaultLowStockThreshold(value: number): void {
    // 验证值是否合法
    if (value < 0) {
      console.error('默认低库存阈值不能为负数');
      return;
    }
    
    // 更新默认阈值
    this.defaultLowStockThreshold = value;
    
    // 保存到本地存储
    localStorage.setItem('defaultLowStockThreshold', value.toString());
    
    // 重新处理低库存物品
    this.processlowStockItems(this.stockItemsSubject.value);
  }

  /**
   * 从本地存储加载默认阈值
   */
  private loadDefaultThreshold(): void {
    const savedThreshold = localStorage.getItem('defaultLowStockThreshold');
    if (savedThreshold) {
      const thresholdValue = parseInt(savedThreshold, 10);
      if (!isNaN(thresholdValue) && thresholdValue >= 0) {
        this.defaultLowStockThreshold = thresholdValue;
      }
    }
  }

  /**
   * 加载库存预警规则
   */
  private loadAlertRules(): void {
    // 从本地存储中加载规则（在真实环境中，这应该从API加载）
    const savedRules = localStorage.getItem('stockAlertRules');
    
    if (savedRules) {
      try {
        const rules = JSON.parse(savedRules) as StockAlertRule[];
        this.alertRulesSubject.next(rules);
      } catch (e) {
        console.error('解析预警规则出错:', e);
        this.alertRulesSubject.next([]);
      }
    } else {
      // 初始默认规则
      const defaultRules: StockAlertRule[] = [
        {
          id: '1',
          isGlobal: true,
          thresholdValue: this.defaultLowStockThreshold,
          priority: 5, // 最低优先级
          isActive: true,
          createdAt: new Date(),
          updatedAt: new Date()
        }
      ];
      
      this.alertRulesSubject.next(defaultRules);
      localStorage.setItem('stockAlertRules', JSON.stringify(defaultRules));
    }
  }

  /**
   * 保存预警规则
   */
  saveAlertRule(rule: StockAlertRule): void {
    const currentRules = [...this.alertRulesSubject.value];
    
    // 如果没有ID，添加新规则
    if (!rule.id) {
      // 生成唯一ID
      rule.id = Date.now().toString();
      rule.createdAt = new Date();
      rule.updatedAt = new Date();
      
      // 添加新规则
      currentRules.push(rule);
    } else {
      // 更新现有规则
      const index = currentRules.findIndex(r => r.id === rule.id);
      
      if (index !== -1) {
        rule.updatedAt = new Date();
        currentRules[index] = rule;
      } else {
        // 规则不存在，添加为新规则
        rule.createdAt = new Date();
        rule.updatedAt = new Date();
        currentRules.push(rule);
      }
    }
    
    // 更新规则列表
    this.alertRulesSubject.next(currentRules);
    
    // 保存到本地存储
    localStorage.setItem('stockAlertRules', JSON.stringify(currentRules));
    
    // 重新处理低库存物品
    this.processlowStockItems(this.stockItemsSubject.value);
  }

  /**
   * 删除预警规则
   */
  deleteAlertRule(id: string): void {
    const currentRules = [...this.alertRulesSubject.value];
    
    // 过滤掉要删除的规则
    const filteredRules = currentRules.filter(rule => rule.id !== id);
    
    // 更新规则列表
    this.alertRulesSubject.next(filteredRules);
    
    // 保存到本地存储
    localStorage.setItem('stockAlertRules', JSON.stringify(filteredRules));
    
    // 重新处理低库存物品
    this.processlowStockItems(this.stockItemsSubject.value);
  }

  /**
   * 错误处理函数
   */
  private handleError(error: any) {
    console.error('库存数据服务错误:', error);
    return throwError(() => new Error('获取库存数据失败。请稍后再试。'));
  }
  
  /**
   * 接收从外部传入的数据并进行处理
   * @param data 库存数据数组
   */
  notifyDataChanged(data: any[]): void {
    if (!data || data.length === 0) {
      console.warn('接收到的数据为空，使用模拟数据代替');
      this.generateMockData();
      return;
    }
    
    try {
      // 尝试将数据转换为StockItem格式
      const stockItems = data.map(item => ({
        id: item.id || String(Math.random()),
        goodsCode: item.goodsCode || '',
        goodsName: item.goodsName || '',
        specification: item.specification || '',
        warehouseId: item.warehouseId || item.warehouseName || '',
        warehouseName: item.warehouseName || '',
        goodsType: item.goodsType || '',
        currentStock: Number(item.currentStock) || 0,
        warningThreshold: Number(item.warningThreshold) || 10,
        unitPrice: Number(item.stockAmount) / (Number(item.currentStock) || 1),
        totalAmount: Number(item.stockAmount) || 0,
        updatedAt: new Date()
      } as StockItem));
      
      // 更新库存物品列表
      this.stockItemsSubject.next(stockItems);
      
      // 处理低库存物品
      this.processlowStockItems(stockItems);
      
      // 计算库存统计数据
      this.calculateStockStats(stockItems);
      
      // 按仓库和类型分组
      this.groupStockByWarehouse(stockItems);
      this.groupStockByType(stockItems);
      
      // 更新时间
      this.lastUpdateTimeSubject.next(new Date());
      
      console.log('成功处理库存数据:', stockItems.length, '条记录');
    } catch (error) {
      console.error('处理传入的数据时出错:', error);
      // 使用模拟数据
      this.generateMockData();
    }
  }
} 